package com.itbaizhan.springsecuritydemo1.config;

import com.itbaizhan.springsecuritydemo1.Hander.MyHander;
import com.itbaizhan.springsecuritydemo1.Hander.MyInvalidSessionStrategy;
import com.itbaizhan.springsecuritydemo1.Hander.MyLoginFailureHandler;
import com.itbaizhan.springsecuritydemo1.Hander.MyLogoutSuccessHandler;
import com.itbaizhan.springsecuritydemo1.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

@Configuration   //配置类
@EnableWebSecurity  //为了加上更详细的配置
public class SecurityConfig {
    
    @Autowired
    private MyUserDetailsService myUserDetailsService;
    private PersistentTokenRepository repository;
    
    //Security详细配置
    @Bean
    public SecurityFilterChain filterChain (HttpSecurity http) throws Exception {
        http.formLogin(form -> {
           form.loginPage("/login.html")//自定义登录页面
               .usernameParameter("username")  //表单中的用户名选项
                   .passwordParameter("password") //表单中的密码
                   .loginProcessingUrl("/login") //登陆的路径
//                   .successForwardUrl("/main") //登录成功的路径
                   .successHandler(new MyHander())
//                   .failureForwardUrl("/fail"); //登录失败的路径
                   .failureHandler(new MyLoginFailureHandler());
        });
        
        //需要登录认证的资源
        http.authorizeHttpRequests(resp ->{
           resp.requestMatchers("/login.html","/fail.html").permitAll();  //不需要认证的资源
           
            resp.requestMatchers("/css/*.css","/js/*.js","/img/**").permitAll();  //静态资源不需要认证
            
            resp.anyRequest().authenticated();  //其余资源都需要认证
        });
        
        //定义会话失效的策略
        http.sessionManagement(session ->{
            session.invalidSessionUrl("/login");
            session.invalidSessionStrategy(new MyInvalidSessionStrategy());
            
            //设置同一账号下只能登录一个浏览器
            session.maximumSessions(1);
        });
        
        //退出登录
        http.logout(logout->{
            logout.logoutUrl("/logout")  //退出登录的url
//                    .logoutSuccessUrl("/login.html")  //退出成功的跳转
                    .logoutSuccessHandler(new MyLogoutSuccessHandler())
                    .clearAuthentication(true) //清除认证状态
                    .invalidateHttpSession(true);
        });
        
        //记住我复选框
        http.rememberMe(rember->{
            rember.userDetailsService(myUserDetailsService)  //认证逻辑对象
                    .tokenRepository(repository)  //持久层对象
                    .tokenValiditySeconds(30);
        });
        
        
        //关闭csrf防护
        http.csrf(csrf ->{
            csrf.disable();
        });
        return http.build();
    }
    
//    //密码编译器
//    @Bean
//    public PasswordEncoder passwordEncoder (){
//        return new BCryptPasswordEncoder();
//    }

}
